package com.shuwen.gcdj.service.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RedisService {
    @Autowired
    private RedisTemplate<String, String> strRedisTemplate;

    public String setString(String key, String value, long timeout) {
        strRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
        return strRedisTemplate.opsForValue().get(key);
    }

    public String getString(String key) {
        return strRedisTemplate.opsForValue().get(key);
    }

    public Boolean delete(String key) {
        return strRedisTemplate.delete(key);
    }

    public List<String> getPipelineString(List<String> keys) {
        // 1.executePipelined 重写 入参 RedisCallback 的doInRedis方法
        List<Object> resultList = strRedisTemplate.executePipelined((RedisCallback<Object>) c -> {
            // 2.connection 打开管道
            c.openPipeline();
            // 3.批量get
            for (String key : keys) {
                c.get(key.getBytes());
            }
            // 这里一定要返回null，最终pipeline的执行结果，才会返回给最外层
            return null;
        });
        log.info("RedisService.getPipelineString(keys = {}) pipeline read result is : {}", keys, resultList);

        if (resultList.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> resp = new ArrayList<>();
        for (Object o : resultList) {
            resp.add(o.toString());
        }

        return resp;
    }

    public Long deleteKeysWithPattern(String pattern) {
        if (pattern == null || pattern.isEmpty()) {
            return 0L;
        }

        try {
            Set<String> keys = strRedisTemplate.keys(pattern);
            if (CollectionUtils.isEmpty(keys)) {
                return 0L;
            }

            Long opNum = strRedisTemplate.delete(keys);
            log.info("RedisService.deleteKeysWithPattern(pattern = {}) affect rows = {}", pattern, opNum);
            return opNum;
        } catch (Exception e) {
            log.error("error: RedisService.deleteKeysWithPattern(pattern = {}) 批量删除redisKey异常", pattern);
            return 0L;
        }
    }
}
